from datetime import datetime
import pkg_resources
pkg_resources.require("SQLAlchemy>=0.3.10")
pkg_resources.require("Elixir>=0.4.0")
# import the basic Elixir classes and functions for declaring the data model
# (see http://elixir.ematia.de/trac/wiki/TutorialDivingIn)
from elixir import Entity, Field, OneToMany, ManyToOne, ManyToMany
from elixir import options_defaults, using_options, setup_all
# import some datatypes for table columns from Elixir
# (see http://www.sqlalchemy.org/docs/04/types.html for more)
from elixir import String, Unicode, Integer, DateTime, UnicodeText,Boolean
from turbogears import identity

options_defaults['autosetup'] = False


# your data model

# class YourDataClass(Entity):
#     pass


# the identity model


class Visit(Entity):
    """
    A visit to your site
    """
    using_options(tablename='visit')

    visit_key = Field(String(40), primary_key=True)
    created = Field(DateTime, nullable=False, default=datetime.now)
    expiry = Field(DateTime)

    def lookup_visit(cls, visit_key):
        return Visit.get(visit_key)
    lookup_visit = classmethod(lookup_visit)


class VisitIdentity(Entity):
    """
    A Visit that is link to a User object
    """
    using_options(tablename='visit_identity')

    visit_key = Field(String(40), primary_key=True)
    user = ManyToOne('User', colname='user_id', use_alter=True)


class Group(Entity):
    """
    An ultra-simple group definition.
    """
    using_options(tablename='tg_group')

    group_id = Field(Integer, primary_key=True)
    group_name = Field(Unicode(16), unique=True)
    display_name = Field(Unicode(255))
    created = Field(DateTime, default=datetime.now)
    users = ManyToMany('User', tablename='user_group')
    permissions = ManyToMany('Permission', tablename='group_permission')


class User(Entity):
    """
    Reasonably basic User definition.
    Probably would want additional attributes.
    """
    using_options(tablename='tg_user')

    user_id = Field(Integer, primary_key=True)
    user_name = Field(Unicode(16), unique=True)
    email_address = Field(Unicode(255), unique=True)
    display_name = Field(Unicode(255))
    password = Field(Unicode(40))
    created = Field(DateTime, default=datetime.now)
    groups = ManyToMany('Group', tablename='user_group')

    def permissions(self):
        p = set()
        for g in self.groups:
            p |= set(g.permissions)
        return p
    permissions = property(permissions)


class Permission(Entity):
    """
    A relationship that determines what each Group can do
    """
    using_options(tablename='permission')

    permission_id = Field(Integer, primary_key=True)
    permission_name = Field(Unicode(16), unique=True)
    description = Field(Unicode(255))
    groups = ManyToMany('Group', tablename='group_permission')


class Category(Entity):
    """
    A forum category
    """
    category_id = Field(Integer,primary_key=True)
    category_name = Field(Unicode(255),unique=True)
    description = Field(UnicodeText)
    channels = OneToMany('Channel')

class Channel(Entity):
    """
    A channel
    """
    channel_id = Field(Unicode(50),primary_key=True)
    channel_name = Field(Unicode(255),unique=True)
    description = Field(UnicodeText)
    category = ManyToOne('Category')
    threads = OneToMany('Thread')
    weight = Field(Integer)
    
class Thread(Entity):
    """
    A Thread
    """
    thread_id = Field(Integer,primary_key=True)
    thread_title = Field(Unicode(255))
    channel = ManyToOne('Channel')
    datecreated = Field(DateTime)
    locked = Field(Boolean)
    posts = OneToMany('Post')

class Post(Entity):
    """
    A Post
    """
    post_id = Field(Integer,primary_key=True)
    thread = ManyToOne('Thread',primary_key=True)
    poster = Field(Unicode(255))
    tripcode = Field(Unicode(255))
    contents = Field(UnicodeText)
    link = Field(String(512))
    ip = Field(String(255))
    http_x_forwarded_for = Field(String(255))
    datetime = Field(DateTime)
    
   
# Set up all Elixir entities declared above

setup_all()
